package safe_queue

import (
	"sync"
)

// SafeQueue 线程安全的队列
type SafeQueue struct {
	queue  []interface{} // 使用切片来存储队列
	mu     sync.Mutex    // 用来保证线程安全
	Cond   *sync.Cond    // 通知机制
	Closed bool          // 队列是否关闭
}

func NewSafeQueue() *SafeQueue {
	q := &SafeQueue{}
	q.Cond = sync.NewCond(&q.mu)
	return q
}

// Enqueue 向队列尾部添加元素
func (q *SafeQueue) Enqueue(value interface{}) bool {
	q.mu.Lock()
	defer q.mu.Unlock()
	// 如果队列已关闭，则返回 false
	if q.Closed {
		return false
	}
	// 向队列尾部添加数据
	q.queue = append(q.queue, value)
	// 通知等待线程
	q.Cond.Signal()
	return true
}

// Dequeue 从队列头部移除元素并返回该元素
func (q *SafeQueue) Dequeue() bool {
	q.mu.Lock()
	defer q.mu.Unlock()

	if len(q.queue) == 0 {
		// 如果队列为空，则返回 false
		return false
	}

	// 从队列头部移除元素
	q.queue = q.queue[1:]

	return true
}

// Front 获取队列头部的元素
func (q *SafeQueue) Front() (interface{}, bool) {
	q.mu.Lock()
	defer q.mu.Unlock()

	if len(q.queue) == 0 {
		// 如果队列为空，则返回 false
		return 0, false
	}

	// 从队列头部移除元素
	value := q.queue[0]

	return value, true
}

// Length 查看队列的当前长度
func (q *SafeQueue) Length() int {
	q.mu.Lock()
	defer q.mu.Unlock()

	return len(q.queue)
}

// Close 关闭任务队列
// 关闭队列后，队列中将不再允许添加新任务
func (q *SafeQueue) Close() {
	q.mu.Lock()
	defer q.mu.Unlock()

	q.Closed = true
	q.Cond.Broadcast() // 添加唤醒逻辑
}
